#!/usr/bin/perl

use Getopt::Std;
getopts("PWLM:") || die "usage: $0 [-PWL -M <cpuspeed>]\n";

if ($opt_P && !defined($opt_M)) {                                                                                                          
	die "ERROR: no cpu speed is set (use -M option).\n";                                                                               
}

$origin_y = 0.02;
$origin_y_step = 0.113;

$sets = 0;
$l = 0;
$max_z = 1;
while (<STDIN>) {
	chop($_);
	s/OP_//g;
	s/_/\\_/g;
	if (!m/^\#/) {
		if (m/^title/) {
			($tmp, $TITLE[$sets]) = split( /=/, $_ );
		} else {
			if (m/^set /) {
                    	        	$CUSTOM_CMD[$l] = $_;
                    		} else {
				if (length($_) < 10) {
					$sets++;
					$l = 0;
				} else {
					(@tmp) = split( / /, $_ );
					for (my $b = 0; $b <= $#{@tmp}; $b++) {
						if ($opt_W) {
							$BUCKETS[$sets][$l][$b] = $tmp[$b]*1.5*2**($b+4);
							if ($opt_M && $opt_P) {
								$BUCKETS[$sets][$l][$b] /= ($opt_M * 2**32);
							}
						} else {
							$BUCKETS[$sets][$l][$b] = $tmp[$b];
						}
						$max_z = $BUCKETS[$sets][$l][$b] if $BUCKETS[$sets][$l][$b] > $max_z;
					}
					$l++;
				}
			}
		}
	}
}
# Handle files with no EOF 
$sets = 1 if !$sets;

$min_x = 4;
$min_x = 3 if defined($opt_L);

$max_y = $#{$BUCKETS[0]};
$max_x = $#{$BUCKETS[0][0]};

if ($opt_M) {
	$div_y = $opt_M/4.0;
	#$div_y *= 10.0 if $max_y/$div_y > 100;
} else {
	$div_y = 1.0;
	$div_y = 4.0 if $max_y > 100;
}

$min_z = 0.1;
if ($opt_W && $opt_M) {
	$min_z = 0.0000001;
}

if (!defined($opt_L)) {
	$X_label_buckets = "Bucket (2^{n-1} <= x < 2^n CPU Cycles)";
} else {
	$X_label_buckets = "\'Bucket number: {/Symbol=14 \353}log_{2}(latency in CPU cycles){/Symbol=14 \373}\'";
}

print <<"END_GNUPLOT";
#!/usr/local/bin/gnuplot

set term push;
#set terminal postscript eps enhanced 'Helvetica' 14;
set term post eps color enha;
#set out 'OP_3D.eps'

set yrange [0:$max_y/$div_y-1.0]
set xrange [$min_x:$max_x+$min_x-1]
#set ztics 0,200

#set border 4095 lt -1 lw 1.000
#set contour both
set logscale z
#set zrange [0.00001:2*$max_z]
#set pm3d at sb corners2color c1 hidden3d 100
set pm3d at s hidden3d 100
set style line 100 lt 0 lw 0.5
#set style line 100 lt -1 lw 0.1
unset hidden3d
unset surf
set view 45,45
#unset hidd
set ticslevel 0

stepf(y) = y<0 ? 0 : 1
r(y) = 1 - stepf(y - 0.0001)
g(y) = 1 - stepf(y - 0.0001) + stepf(y - 0.0001)*(0.75 - y)
b(y) = 1 - stepf(y - 0.0001)
set palette model RGB functions r(gray),g(gray),b(gray)

END_GNUPLOT

#print "set x2range [$min_x:$max_x+$min_x-1]\n" if $opt_P;

for (my $s = 0; $s < $sets; $s++) {
	if ($opt_W) {
		if ($opt_M && $opt_P) {
			print "set label \'Total delay (sec)\' at graph -0.27,0.0,0.5 center rotate\n";
		} else {
			print "set label \'Total delay (CPU cycles)\' at graph -0.27,0.0,0.5 center rotate\n";
		}
	} else {
		print "set label \'Number of operations\' at graph -0.2,0.0,0.5 center rotate\n";
	}

	print "set label $X_label_buckets at graph 0.5,-0.2 center rotate by -25\n";

	print "set label \'Elapsed time (";
	if ($opt_M && $opt_P) {
		print $div_y," x " if $div_y != $opt_M/4.0;
		print "sec"
	} else {
		print $div_y," x " if $div_y != 1.0;
		print "2^{32} CPU cycles";
	}
	print ")\' at graph 1.2,0.5 center rotate by 25\n";
	
	print "set label \'z\' at graph 0.0,0.0,1.1 center\n";
	print "set label \'y\' at graph 1.05,1.05 center rotate by 25\n";
	print "set label \'x\' at graph 0.97,-0.07 center rotate by -25\n";
	
        print $CUSTOM_CMD[$l],"\n";
	
	print "splot '-' matrix t ''\n";
	for (my $ll = 0; $ll < $max_y; $ll+=$div_y) {
	    if (!defined($opt_L)) {
	    	print "0 0 0 0 ";
	    } else {
	        print "0 0 0 ";
	    }
	    for (my $i = 0; $i < $max_x; $i++) {
	    	my $ll_int = $ll;
	    	my $z = 0;
	    	for (my $ll_acc = 0; $ll_acc < $div_y; $ll_acc++) {
			$z += $BUCKETS[$s][$ll_int + $ll_acc][$i];
		}
		$z = $min_z if $z == 0;
		print $z," ";
	    }
	    print "\n";
	}
	print "e\n";
};

print "set nomultiplot; set out; set term pop\n";
